package co.yixiang.yshop.module.crm.service.crmclues;

import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.framework.mybatis.core.query.LambdaQueryWrapperX;
import co.yixiang.yshop.framework.redis.util.redis.RedisUtil;
import co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils;
import co.yixiang.yshop.module.crm.controller.admin.crmcustomer.vo.CrmCustomerImportVO;
import co.yixiang.yshop.module.crm.controller.admin.crmcustomer.vo.CrmCustomerSaveReqVO;
import co.yixiang.yshop.module.crm.controller.admin.crmcustomer.vo.CrmCustomerTransferVO;
import co.yixiang.yshop.module.crm.controller.admin.crmcustomer.vo.CustomerImportRespVO;
import co.yixiang.yshop.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO;
import co.yixiang.yshop.module.crm.dal.dataobject.crmcustomercontacts.CrmCustomerContactsDO;
import co.yixiang.yshop.module.crm.dal.dataobject.crmrecord.CrmRecordDO;
import co.yixiang.yshop.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import co.yixiang.yshop.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import co.yixiang.yshop.module.crm.enums.CluesStatusEnum;
import co.yixiang.yshop.module.crm.enums.CustomerTypesEnum;
import co.yixiang.yshop.module.crm.enums.RelationEnum;
import co.yixiang.yshop.module.crm.enums.TypesEnum;
import co.yixiang.yshop.module.crm.service.crmoperatelog.CrmOperatelogService;
import co.yixiang.yshop.module.system.api.user.AdminUserApi;
import co.yixiang.yshop.module.system.dal.dataobject.user.AdminUserDO;
import co.yixiang.yshop.module.system.dal.mysql.user.AdminUserMapper;
import co.yixiang.yshop.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.HashMap;
import java.util.stream.Collectors;

import co.yixiang.yshop.module.crm.controller.admin.crmclues.vo.*;
import co.yixiang.yshop.module.crm.dal.dataobject.crmclues.CrmCluesDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.framework.common.pojo.PageParam;
import co.yixiang.yshop.framework.common.util.object.BeanUtils;

import co.yixiang.yshop.module.crm.dal.mysql.crmclues.CrmCluesMapper;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.crm.enums.ErrorCodeConstants.*;

import co.yixiang.yshop.module.crm.controller.admin.crmbills.vo.CrmBillsSaveReqVO;
import co.yixiang.yshop.module.crm.dal.dataobject.crmbills.CrmBillsDO;
import co.yixiang.yshop.module.crm.dal.mysql.crmbills.CrmBillsMapper;
import co.yixiang.yshop.module.crm.service.crmbills.CrmBillsService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;

/**
 * 线索 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class CrmCluesServiceImpl implements CrmCluesService {

    @Resource
    private CrmCluesMapper cluesMapper;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private CrmCustomerMapper customerMapper;
    @Resource
    private CrmRecordMapper crmRecordMapper;
    @Resource
    private AdminUserMapper userMapper;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private CrmOperatelogService crmOperatelogService;
    @Resource
    private CrmBillsService billsService;
    @Resource
    private CrmBillsMapper billsMapper;

    @Override
    public Long createClues(CrmCluesSaveReqVO createReqVO) {
        // 插入
        CrmCluesDO clues = BeanUtils.toBean(createReqVO, CrmCluesDO.class);
        clues.setOwnerUserId(SecurityFrameworkUtils.getLoginUserId());
        clues.setCreateTime(LocalDateTime.now());
        cluesMapper.insert(clues);
        // 返回
        return clues.getId();
    }

    @Override
    public void updateClues(CrmCluesSaveReqVO updateReqVO) {
        // 校验存在
        validateCluesExists(updateReqVO.getId());
        // 更新
        CrmCluesDO updateObj = BeanUtils.toBean(updateReqVO, CrmCluesDO.class);
        cluesMapper.updateById(updateObj);
    }

    @Override
    public void deleteClues(Long id) {
        // 校验存在
        validateCluesExists(id);
        // 删除
        cluesMapper.deleteById(id);

        //删除记录
        crmRecordMapper.delete(new LambdaQueryWrapper<CrmRecordDO>()
                .eq(CrmRecordDO::getTypes, TypesEnum.CLUES.getValue())
                .eq(CrmRecordDO::getTypesId,id));
    }

    private void validateCluesExists(Long id) {
        if (cluesMapper.selectById(id) == null) {
            throw exception(CLUES_NOT_EXISTS);
        }
    }

    @Override
    public CrmCluesDO getClues(Long id) {
        return cluesMapper.selectById(id);
    }

    @Override
    public PageResult<CrmCluesRespVO> getCluesPage(CrmCluesPageReqVO pageReqVO) {
        // 添加调试日志 - 打印输入参数
        System.out.println("CrmCluesService.getCluesPage - 输入参数: " + pageReqVO.toString());

        // 处理导出功能 - 检查是否有 ownerUserIds 参数 (多负责人筛选)
        if (pageReqVO.getOwnerUserIds() != null && !pageReqVO.getOwnerUserIds().isEmpty()) {
            System.out.println("使用导出专用查询 - 支持多负责人查询: " + pageReqVO.getOwnerUserIds());
            return cluesMapper.selectExportPage(pageReqVO);
        }

        // 处理公海线索查询
        // 兼容两种方式：1. type=open 2. status=-1
        if (CustomerTypesEnum.OPEN.getValue().equals(pageReqVO.getType()) ||
            (pageReqVO.getStatus() != null && CluesStatusEnum.STATUS_NEG_1.getValue().equals(pageReqVO.getStatus()))) {
            System.out.println("执行公海线索查询: type=open 或 status=-1");
            return cluesMapper.selectPublicSeaPage(pageReqVO);
        }

        // 处理普通线索查询 - 通过 selectPage 查询
        List<Long> ids = new ArrayList<>();
        Long adminId = SecurityFrameworkUtils.getLoginUserId();

        // 根据 relation 参数决定查询范围
        if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
            // 我的线索
            ids.add(adminId);
            System.out.println("查询我的线索: adminId=" + adminId);
        } else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
            // 下属的线索
            ids = adminUserApi.getUserListBySubordinateIds(adminId);
            System.out.println("查询下属线索: 下属IDs=" + ids);
        }

        // 返回查询结果
        return cluesMapper.selectPage(pageReqVO, ids);
    }

    @Override
    public void openClues(Long id) {
        // 获取线索对象并验证存在性
        CrmCluesDO crmCluesDO = cluesMapper.selectById(id);
        if (crmCluesDO == null) {
            throw exception(CLUES_NOT_EXISTS);
        }

        // 记录原始信息，用于日志
        Long originalOwnerId = crmCluesDO.getOwnerUserId();

        // 更新线索状态为公海状态（无效线索）
        Integer originalStatus = crmCluesDO.getStatus();
        // 将状态更新为公海状态（-1）
        crmCluesDO.setStatus(CluesStatusEnum.STATUS_NEG_1.getValue());

        // 不再清空负责人ID，只改变状态
        // crmCluesDO.setOwnerUserId(0L); // 移除此行

        cluesMapper.updateById(crmCluesDO);

        // 获取负责人名称（如果存在）
        String ownerName = "--";
        if (originalOwnerId != null && originalOwnerId > 0) {
            AdminUserDO user = userMapper.selectById(originalOwnerId);
            if (user != null) {
                ownerName = user.getNickname();
            }
        }

        // 添加操作日志，记录状态变更和原负责人
        String logContent = String.format("放入线索公海 (原状态:%d, 负责人:%s)",
                                        originalStatus, ownerName);
        crmOperatelogService.createLog(logContent, id, 0L, originalOwnerId);
    }

    @Override
    public void receiveClues(Long id) {
        // 获取线索对象并验证存在性
        CrmCluesDO crmCluesDO = cluesMapper.selectById(id);
        if (crmCluesDO == null) {
            throw exception(CLUES_NOT_EXISTS);
        }

        // 检查线索是否在公海（status=-1）
        if (!CluesStatusEnum.STATUS_NEG_1.getValue().equals(crmCluesDO.getStatus())) {
            throw exception(new ErrorCode(202411201, "该线索不在公海，无法领取"));
        }

        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();

        // 添加领取数量限制
        limitClues(currentUserId);

        // 更新线索状态为未转客户(0)
        crmCluesDO.setStatus(CluesStatusEnum.STATUS_0.getValue());
        // 更新线索的所有者和相关时间
        crmCluesDO.setOwnerUserId(currentUserId);
        crmCluesDO.setCollectTime(LocalDateTime.now());
        crmCluesDO.setFollowTime(LocalDateTime.now());
        cluesMapper.updateById(crmCluesDO);

        // 添加操作日志
        crmOperatelogService.createLog("从公海领取线索", id, 0L, 0L);
    }

    /**
     * 限制领取线索的数量
     * @param uid 用户ID
     */
    private void limitClues(Long uid){
        // 获取系统配置的线索数量上限
        Integer cluesNum = RedisUtil.get("cluesNum");
        if(cluesNum == null){
            return; // 如果未设置限制，则不进行检查
        }

        // 查询该用户当前已有的线索数量
        Long count = cluesMapper.selectCount(new LambdaQueryWrapper<CrmCluesDO>()
                .eq(CrmCluesDO::getOwnerUserId, uid));

        // 如果已达到或超过上限，则抛出异常
        if(count >= cluesNum){
            throw exception(new ErrorCode(202411200,
                String.format("您当前已有%d条线索，已达到系统设置的上限%d条。请先处理现有线索或联系管理员提高限制。",
                count, cluesNum)));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createCustomer(CrmCustomerSaveReqVO createReqVO) {
        CrmCluesDO crmCluesDO = cluesMapper.selectById(createReqVO.getId());
        if (crmCluesDO == null) {
            throw exception(CLUES_NOT_EXISTS);
        }
        if(CluesStatusEnum.STATUS_1.getValue().equals(crmCluesDO.getStatus())){
            throw exception(new ErrorCode(202411160,"已经转化成客户！"));
        }
        createReqVO.setId(null);
        CrmCustomerDO customerDO = BeanUtils.toBean(createReqVO,CrmCustomerDO.class);
        customerDO.setOwnerUserId(SecurityFrameworkUtils.getLoginUserId());
        customerDO.setNextTime(LocalDateTime.now());
        customerDO.setCollectTime(LocalDateTime.now());
        customerMapper.insert(customerDO);

        //更新线索
        crmCluesDO.setStatus(CluesStatusEnum.STATUS_1.getValue());
        crmCluesDO.setCustomerId(customerDO.getId());
        cluesMapper.updateById(crmCluesDO);

        //是否更新跟踪记录
        if(ShopCommonEnum.ENABLE_1.getValue().equals(createReqVO.getIsTransfer())){
            crmRecordMapper.update(CrmRecordDO.builder()
                    .types(TypesEnum.CUSTOMER.getValue())
                    .typesId(customerDO.getId()).build(),
                    new LambdaQueryWrapper<CrmRecordDO>().eq(CrmRecordDO::getTypesId,crmCluesDO.getId()));
        }
    }


    @Override
    public CustomerImportRespVO importList(List<CrmCluesImportVO> importUsers, String deptId, String adminIds,
                                           Integer averageType) {
        CustomerImportRespVO respVO = CustomerImportRespVO.builder().createNames(new ArrayList<>())
                .failureNames(new LinkedHashMap<>()).build();
        //处理客户归属方案
        //如果只选择了机构没有选择用户直接获取当前部门下的用户
        List<Long> userList = null;
        if(StrUtil.isNotEmpty(deptId) && StrUtil.isEmpty(adminIds)){
            Set<Long> deptIds = adminUserService.getDeptCondition(Long.valueOf(deptId));
            List<AdminUserDO> adminUserDOS =  userMapper.selectList(new LambdaQueryWrapperX<AdminUserDO>()
                    .in(AdminUserDO::getDeptId,deptIds));
            userList = adminUserDOS.stream().map(AdminUserDO::getId).collect(Collectors.toList());
            if(userList.isEmpty()){
                throw exception(new ErrorCode(202409110,"当前部门下没有用户，清重新选择"));
            }
        }else{
            userList = StrUtil.split(adminIds,",").stream().map(Long::parseLong).collect(Collectors.toList());
        }


        int i = 1;
        int j = 0;
        int adminCount = userList.size();
        for (CrmCluesImportVO importVO : importUsers){
            // 允许导入重复数据，不再检查是否已存在

            CrmCluesDO crmCluesDO = BeanUtils.toBean(importVO, CrmCluesDO.class);

            // 处理可能缺少的字段
            if (crmCluesDO.getCreateTime() == null) {
                crmCluesDO.setCreateTime(LocalDateTime.now());
            }

            // 设置线索状态
            crmCluesDO.setStatus(CluesStatusEnum.STATUS_0.getValue());

            Long adminId = 0L;
            if(ShopCommonEnum.AVG_1.getValue().equals(averageType)){
                //平均分配
                adminId = userList.get(j);
                if(j == (adminCount - 1)){
                    j = 0;
                }else{
                    j++;
                }
            }else{
                //随机分配
                Random random = new Random();
                int num = random.nextInt(adminCount);
                adminId = userList.get(num);
            }
            crmCluesDO.setOwnerUserId(adminId);
            crmCluesDO.setCollectTime(LocalDateTime.now());

            try {
                // 保存线索
                cluesMapper.insert(crmCluesDO);
                respVO.getCreateNames().add("第" + i + "行:导入成功用户名->" + (StrUtil.isNotEmpty(importVO.getName()) ? importVO.getName() : "未知"));
            } catch (Exception e) {
                // 如果插入失败，记录错误信息
                respVO.getFailureNames().put("第" + i + "行:", "插入数据库失败：" + e.getMessage());
            }
            i++;
        }
        return respVO;
    }

    @Override
    public CustomerImportRespVO importLegacyList(List<CrmCluesImportVO> importUsers, String deptId, String adminIds,
                                                 Integer averageType) {
        CustomerImportRespVO respVO = CustomerImportRespVO.builder().createNames(new ArrayList<>())
                .failureNames(new LinkedHashMap<>()).build();

        //处理客户归属方案
        //如果只选择了机构没有选择用户直接获取当前部门下的用户
        List<Long> userList = null;
        if(StrUtil.isNotEmpty(deptId) && StrUtil.isEmpty(adminIds)){
            Set<Long> deptIds = adminUserService.getDeptCondition(Long.valueOf(deptId));
            List<AdminUserDO> adminUserDOS = userMapper.selectList(new LambdaQueryWrapperX<AdminUserDO>()
                    .in(AdminUserDO::getDeptId,deptIds));
            userList = adminUserDOS.stream().map(AdminUserDO::getId).collect(Collectors.toList());
            if(userList.isEmpty()){
                throw exception(new ErrorCode(202409110,"当前部门下没有用户，请重新选择"));
            }
        } else {
            userList = StrUtil.split(adminIds,",").stream().map(Long::parseLong).collect(Collectors.toList());
        }

        int i = 1;
        int j = 0;
        int adminCount = userList.size();
        for (CrmCluesImportVO importVO : importUsers) {
            // 允许导入重复数据，不再检查是否已存在

            CrmCluesDO crmCluesDO = BeanUtils.toBean(importVO, CrmCluesDO.class);

            // 处理旧格式可能缺少的字段
            if (crmCluesDO.getCreateTime() == null) {
                crmCluesDO.setCreateTime(LocalDateTime.now());
            }

            // 设置线索状态
            crmCluesDO.setStatus(CluesStatusEnum.STATUS_0.getValue());

            // 分配用户
            Long adminId;
            if(ShopCommonEnum.AVG_1.getValue().equals(averageType)){
                //平均分配
                adminId = userList.get(j);
                if(j == (adminCount - 1)){
                    j = 0;
                }else{
                    j++;
                }
            }else{
                //随机分配
                Random random = new Random();
                int num = random.nextInt(adminCount);
                adminId = userList.get(num);
            }
            crmCluesDO.setOwnerUserId(adminId);
            crmCluesDO.setCollectTime(LocalDateTime.now());

            try {
                // 保存线索
                cluesMapper.insert(crmCluesDO);
                respVO.getCreateNames().add("第" + i + "行:导入成功用户名->" + (StrUtil.isNotEmpty(importVO.getName()) ? importVO.getName() : "未知"));
            } catch (Exception e) {
                // 如果插入失败，记录错误信息
                respVO.getFailureNames().put("第" + i + "行:", "插入数据库失败：" + e.getMessage());
            }
            i++;
        }
        return respVO;
    }

    @Override
    public void transfer(CrmCluesTransferVO transferVO) {
        //客户
        List<CrmCluesDO> crmCluesDOS = cluesMapper.selectList(new LambdaQueryWrapper<CrmCluesDO>().
                in(CrmCluesDO::getId,transferVO.getCluesIds()));
        if(crmCluesDOS == null || crmCluesDOS.isEmpty()){
            throw exception(new ErrorCode(202409111,"线索信息不存在"));
        }

        int adminCount = transferVO.getOwnerAdminIds().size();
        int i = 0;
        for (CrmCluesDO crmCluesDO : crmCluesDOS){
            Long adminId;
            if(ShopCommonEnum.AVG_1.getValue().equals(transferVO.getAverageType())){
                //平均分配
                adminId = transferVO.getOwnerAdminIds().get(i);
                if(i == (adminCount - 1)){
                    i = 0;
                }else{
                    i++;
                }
            }else{
                //随机分配
                Random random = new Random();
                int num = random.nextInt(adminCount);
                adminId = transferVO.getOwnerAdminIds().get(num);
            }
            crmCluesDO.setOwnerUserId(adminId);
            crmCluesDO.setCollectTime(LocalDateTime.now());
            // 更新分配时间
            crmCluesDO.setAssignTime(LocalDateTime.now());
            cluesMapper.updateById(crmCluesDO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long transferToBill(CrmCluesBillTransferVO transferVO) {
        // 校验线索是否存在
        CrmCluesDO clues = validateCluesExistsAndGet(transferVO.getCluesId());

        // 查询是否已有相同门店和日期的账单
        CrmBillsDO existingBill = billsMapper.selectOne(new LambdaQueryWrapper<CrmBillsDO>()
                .eq(CrmBillsDO::getStoreName, transferVO.getStoreName())
                .eq(CrmBillsDO::getBillingDate, transferVO.getBillingDate()));

        // 创建或更新账单
        CrmBillsSaveReqVO billsVO = new CrmBillsSaveReqVO();
        billsVO.setStoreName(transferVO.getStoreName());
        billsVO.setBillingDate(transferVO.getBillingDate());
        billsVO.setOwnerUserId(clues.getOwnerUserId());

        Long billId;
        if (existingBill != null) {
            // 更新已有账单
            billsVO.setId(existingBill.getId());

            // 注册数加1
            Integer registerCount = existingBill.getRegisterCount() != null ? existingBill.getRegisterCount() + 1 : 1;
            billsVO.setRegisterCount(registerCount);

            // 累加花费
            BigDecimal expenditure = existingBill.getExpenditure() != null ?
                    existingBill.getExpenditure().add(transferVO.getExpenditure()) :
                    transferVO.getExpenditure();
            billsVO.setExpenditure(expenditure);

            // 计算单价 = 总花费 / 注册数
            if (registerCount > 0) {
                BigDecimal unitPrice = expenditure.divide(new BigDecimal(registerCount), 2, RoundingMode.HALF_UP);
                billsVO.setUnitPrice(unitPrice);
            }

            // 处理充值金额
            BigDecimal rechargeAmount = existingBill.getRechargeAmount() != null ?
                    existingBill.getRechargeAmount() : BigDecimal.ZERO;

            // 如果有新的充值金额，累加到现有充值金额
            if (transferVO.getRechargeAmount() != null) {
                rechargeAmount = rechargeAmount.add(transferVO.getRechargeAmount());
            }
            billsVO.setRechargeAmount(rechargeAmount);

            // 计算余额 = 充值金额 - 花费
            BigDecimal balance = rechargeAmount.subtract(expenditure);
            billsVO.setBalance(balance);

            // 处理男女数量
            // 获取当前的男女比例并转换为数量
            BigDecimal maleCount = existingBill.getMalePercentage() != null ?
                    existingBill.getMalePercentage() : BigDecimal.ZERO;
            BigDecimal femaleCount = existingBill.getFemalePercentage() != null ?
                    existingBill.getFemalePercentage() : BigDecimal.ZERO;

            // 如果转换的线索是男性，男性数量加1
            if (transferVO.getMalePercentage() != null && transferVO.getMalePercentage().compareTo(BigDecimal.ZERO) > 0) {
                maleCount = maleCount.add(BigDecimal.ONE);
            }
            // 如果转换的线索是女性，女性数量加1
            else if (transferVO.getFemalePercentage() != null && transferVO.getFemalePercentage().compareTo(BigDecimal.ZERO) > 0) {
                femaleCount = femaleCount.add(BigDecimal.ONE);
            }

            billsVO.setMalePercentage(maleCount);
            billsVO.setFemalePercentage(femaleCount);

            billsService.updateBills(billsVO);
            billId = existingBill.getId();
        } else {
            // 创建新账单
            billsVO.setRegisterCount(1); // 首次注册为1
            billsVO.setExpenditure(transferVO.getExpenditure());
            billsVO.setUnitPrice(transferVO.getExpenditure()); // 首次单价等于花费

            // 设置充值金额
            BigDecimal rechargeAmount = transferVO.getRechargeAmount() != null ?
                    transferVO.getRechargeAmount() : BigDecimal.ZERO;
            billsVO.setRechargeAmount(rechargeAmount);

            // 计算余额 = 充值金额 - 花费
            BigDecimal balance = rechargeAmount.subtract(transferVO.getExpenditure());
            billsVO.setBalance(balance);

            // 设置男女数量 - 根据传入的值确定是男是女
            // 如果transferVO的malePercentage有值且大于0，则设置为男性1，女性0
            // 如果transferVO的femalePercentage有值且大于0，则设置为男性0，女性1
            if (transferVO.getMalePercentage() != null && transferVO.getMalePercentage().compareTo(BigDecimal.ZERO) > 0) {
                billsVO.setMalePercentage(BigDecimal.ONE);
                billsVO.setFemalePercentage(BigDecimal.ZERO);
            } else if (transferVO.getFemalePercentage() != null && transferVO.getFemalePercentage().compareTo(BigDecimal.ZERO) > 0) {
                billsVO.setMalePercentage(BigDecimal.ZERO);
                billsVO.setFemalePercentage(BigDecimal.ONE);
            } else {
                // 默认情况，如果没有指定性别，设置为男性0，女性0
                billsVO.setMalePercentage(BigDecimal.ZERO);
                billsVO.setFemalePercentage(BigDecimal.ZERO);
            }

            billId = billsService.createBills(billsVO);
        }

        // 逻辑删除线索（将status设置为-1表示无效线索）
        clues.setStatus(CluesStatusEnum.STATUS_NEG_1.getValue()); // 使用枚举值
        cluesMapper.updateById(clues);

        return billId;
    }

    /**
     * 校验线索是否存在，并返回线索对象
     *
     * @param id 线索ID
     * @return 线索对象
     */
    private CrmCluesDO validateCluesExistsAndGet(Long id) {
        CrmCluesDO clues = cluesMapper.selectById(id);
        if (clues == null) {
            throw exception(CLUES_NOT_EXISTS);
        }
        return clues;
    }

    @Override
    public PageResult<CrmCluesRespVO> getPublicSeaCluesPage(CrmCluesPageReqVO pageReqVO) {
        // 调用专门的公海线索查询方法
        System.out.println("服务层 - 执行公海线索查询");
        return cluesMapper.selectPublicSeaPage(pageReqVO);
    }

    @Override
    public Map<String, Long> getCluesChannelDistribution(Long loginUserId) {
        // 渠道分布统计
        return getCluesGroupCount(loginUserId, "channel_source");
    }

    @Override
    public Map<String, Long> getCluesIncomeDistribution(Long loginUserId) {
        // 收入分布统计
        return getCluesGroupCount(loginUserId, "income");
    }

    @Override
    public Map<String, Long> getCluesEducationDistribution(Long loginUserId) {
        // 学历分布统计
        return getCluesGroupCount(loginUserId, "education");
    }

    @Override
    public Map<String, Long> getCluesGenderDistribution(Long loginUserId) {
        // 性别分布统计
        return getCluesGroupCount(loginUserId, "sex");
    }

    @Override
    public Map<String, Long> getCluesMarriageDistribution(Long loginUserId) {
        // 婚姻状况分布统计
        return getCluesGroupCount(loginUserId, "married");
    }

    @Override
    public Map<String, Long> getCluesAgeDistribution(Long loginUserId) {
        // 年龄分布统计 - 只统计18-50岁范围
        Map<String, Long> allAgeDistribution = getCluesGroupCount(loginUserId, "age");
        Map<String, Long> filteredAgeDistribution = new HashMap<>();
        
        for (Map.Entry<String, Long> entry : allAgeDistribution.entrySet()) {
            String ageStr = entry.getKey();
            Long count = entry.getValue();
            
            // 提取年龄数字
            String ageNumber = ageStr.replaceAll("[^0-9]", "");
            if (!ageNumber.isEmpty()) {
                int age = Integer.parseInt(ageNumber);
                // 只保留18-50岁的数据
                if (age >= 18 && age <= 50) {
                    filteredAgeDistribution.put(ageStr, count);
                }
            }
        }
        
        return filteredAgeDistribution;
    }

    /**
     * 通用分组统计方法
     * @param loginUserId 当前登录用户ID
     * @param groupField 需要分组的字段名
     * @return Map<分组值, 数量>
     */
    private Map<String, Long> getCluesGroupCount(Long loginUserId, String groupField) {
        // 判断是否为超级管理员（ID=1为超级管理员）
        boolean isAdmin = loginUserId != null && loginUserId == 1L;
        // 构建查询条件
        QueryWrapper<CrmCluesDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(groupField + " as groupValue", "count(*) as cnt");
        queryWrapper.eq("status", 0);
        if (!isAdmin) {
            queryWrapper.eq("owner_user_id", loginUserId);
        }
        queryWrapper.groupBy(groupField);

        // 查询数据库
        List<Map<String, Object>> resultList = cluesMapper.selectMaps(queryWrapper);

        // 组装结果
        Map<String, Long> result = new HashMap<>();
        if (resultList != null) {
            for (Map<String, Object> map : resultList) {
                String key = map.get("groupValue") == null ? "未知" : map.get("groupValue").toString();
                Long value = map.get("cnt") == null ? 0L : Long.parseLong(map.get("cnt").toString());
                result.put(key, value);
            }
        }
        return result;
    }



}
